package com.software.graduationproject.commons.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.software.graduationproject.commons.enums.ResultCodes;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * 返回结果集
 * @param <T>
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class Result<T> implements Serializable {
    @ApiModelProperty("返回标志")
    private boolean success;
    @ApiModelProperty("返回编码")
    private Integer code;
    @ApiModelProperty("返回数据")
    private T data;
    @ApiModelProperty("返回消息")
    private String message;
    @ApiModelProperty("返回时间")
    private Long timestamp;

    private Result() {
    }
    public Result(final boolean success, final Integer code, final T data, final String message, final Long timestamp) {
        this.success = success;
        this.code = code;
        this.data = data;
        this.message = message;
        this.timestamp = timestamp;
    }

    private static <T> boolean success() {
        return true;
    }

    private static <T> Integer code() {
        return ResultCodes.SUCCESS.status;
    }

    private static <T> T data() {
        return null;
    }

    private static <T> String message() {
        return ResultCodes.SUCCESS.message;
    }

    private static <T> Long timestamp() {
        return (new Date()).getTime();
    }

    public static <T> ResultBuilder<T> builder() {
        return new ResultBuilder();
    }

    public static class ResultBuilder<T> {
        private boolean successSet;
        private boolean successValue;
        private boolean codeSet;
        private Integer codeValue;
        private boolean dataSet;
        private T dataValue;
        private boolean messageSet;
        private String messageValue;
        private boolean timestampSet;
        private Long timestampValue;

        ResultBuilder() {
        }

        public ResultBuilder<T> success(final boolean success) {
            this.successValue = success;
            this.successSet = true;
            return this;
        }

        public ResultBuilder<T> code(final Integer code) {
            this.codeValue = code;
            this.codeSet = true;
            return this;
        }

        public ResultBuilder<T> data(final T data) {
            this.dataValue = data;
            this.dataSet = true;
            return this;
        }

        public ResultBuilder<T> message(final String message) {
            this.messageValue = message;
            this.messageSet = true;
            return this;
        }

        public ResultBuilder<T> timestamp(final Long timestamp) {
            this.timestampValue = timestamp;
            this.timestampSet = true;
            return this;
        }

        public Result<T> build() {
            boolean success$value = this.successValue;
            if (!this.successSet) {
                success$value = Result.success();
            }

            Integer code$value = this.codeValue;
            if (!this.codeSet) {
                code$value = Result.code();
            }

            T data$value = this.dataValue;
            if (!this.dataSet) {
                data$value = Result.data();
            }

            String message$value = this.messageValue;
            if (!this.messageSet) {
                message$value = Result.message();
            }

            Long timestamp$value = this.timestampValue;
            if (!this.timestampSet) {
                timestamp$value = Result.timestamp();
            }

            return new Result(success$value, code$value, data$value, message$value, timestamp$value);
        }

        public String toString() {
            return "Result.ResultBuilder(successValue=" + this.successValue + ", codeValue=" + this.codeValue + ", dataValue=" + this.dataValue + ", messageValue=" + this.messageValue + ", timestampValue=" + this.timestampValue + ")";
        }
    }
}
